// 331. 走方格 https://oj.rnd.huawei.com/problems/331/submissions
//小华现在有一个M*N的矩形，这M*N个矩形可以分割成M*N个等大的正方形，如下所示：
// 01—02—03—04
// |  |  |  |
// 05—06—07—08
// |　|  |  |
// 09—10—11—12
//于是就有(M+1)*(N+1)个点，这些点都与相邻的点之间都有边，长度都为1，最左上角的点是1号，
//先按照每行依次递增，再按照列，如上图所示。对于每个点，都有两种可行路径：
//(1)向下走，用D表示
//(2)向右走，用R表示
//可以进行(1)向下(2)向右，从1点走到(M+1)*(N+1)点，此时小华添加了两个必要动作，
//首先给出动作的定义。动作是指从某一点开始走一段规定的行进模式。
//从1点到(M+1)*(N+1)点中必须出现小华给定的两个动作，例如：
// 01—02—03—04
//|  |  |  |
// 05—06—07—08
//|  |  |  |
// 09—10—11—12
//小华说，必须要走这两个动作，(1)RRD和(2)DDR。
//那么就一共有1种走法：RRDDR，简单的说，就是再也找不到其他的可行序列同时包含这两个串。
//于是小华想知道，在必须出现这2种行进模式的情况下，从1号点走到(M+1)*(N+1)号点一共有多少种走法？
//输入 数据的第一行输入一个正整数T(1 <= T <= 10)，表示有T组测试数据。
//每组测试数据的第一行输入两个正整数M, N(1 <= M, N <=
// 100)，M表示列数，N表示行数。
//下面两行每行输入一个字符串，只包含“R”和“D”两种字符，长度不超过100，保证不会出现空串，相同串。
//输出 对于每组测试数据，给出走法总数 MOD 1000000007的值。
//输入 2
// 3 2
// RRD
// DDR
// 3 2
// R
// D
//输出 1
// 10
//提示AC自动机上的DP。
//虽然只有2个串，但是仍然需要用AC自动机来表示划分状态，用AC自动机标记状态后，然后使用动态规划。
//动态规划的状态是dp[M][N][st][2-bit]，其中M和N表示当前走到了第N行第M列，
// st表示的是当前的AC自动机状态，2-bit则是当前有了几个串，0表示1个串都没有，
// 1表示有了第1个串，2表示有了第2个串，3表示2个串都出现了，
//那么只需根据自动机的转移，相应的转移到[M+1][N]和[M][N+1]的dp的状态即可，
//复杂度O(M * N * len(s))。
//首先要写Trie树，再构建AC自动机，然后是4维动态规划，
//最后统计最末一个节点的某个状态的个数之和。状态转移和统计过程中加法还要一直模一个巨大的数

#include <string.h>

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define DEBUG
#ifdef DEBUG
#define PF(...) printf(__VA_ARGS__)
#else
#define PF(...)
#endif

#define MAX_CH 2
#define GET_IDX(c) ((c) == 'D' ? 0 : 1)
const int MAX_NODE = 300;
#define mod(x) ((x) % 1000000007)
int nxt[MAX_NODE][MAX_CH], tail[MAX_NODE], f[MAX_NODE], size, bit_tag[MAX_NODE];
int m, n;
#define BIT_L (2)
#define MAX_L 101
int dp[MAX_L][MAX_L][MAX_NODE][(1 << BIT_L)];
void init() {
  size = 1;
  memset(dp, 0, sizeof(dp));
  memset(nxt[0], 0, sizeof(nxt[0]));
  memset(tail, 0, sizeof(tail));
  memset(f, 0, sizeof(f));
  memset(bit_tag, 0, sizeof(bit_tag));
}
int newnode() {
  memset(nxt[size], 0, sizeof(nxt[size]));
  f[size] = tail[size] = 0;
  bit_tag[size] = 0;
  return size++;
}
void insert(string s, int bit) {
  int p = 0;
  for (size_t i = 0; i < s.size(); i++) {
    int& x = nxt[p][GET_IDX(s[i])];
    p = x ? x : (x = newnode());
  }
  tail[p]++;
  bit_tag[p] = bit;
}
void makenxt() {
  queue<int> q;
  f[0] = 0;
  for (int i = 0; i < MAX_CH; i++) {
    int v = nxt[0][i];
    if (!v) continue;
    f[v] = 0;
    q.push(v);
  }
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = 0; i < MAX_CH; i++) {
      int v = nxt[u][i];
      if (v) {
        q.push(v);
        f[v] = nxt[f[u]][i];
      } else
        nxt[u][i] = nxt[f[u]][i];
    }
  }
}
int ac_next(char c, int v, int& flag) {
  flag = 0;
  while (v && !nxt[v][GET_IDX(c)]) v = f[v];
  v = nxt[v][GET_IDX(c)];
  int tmp = v;
  while (tmp) {
    flag |= bit_tag[tmp];
    tmp = f[tmp];
  }
  return v;
}
void DP() {
  int flag = 0, nxt_st = 0;
  dp[0][0][0][0] = 1;
  for (int i = 0; i <= m; i++) {
    for (int j = 0; j <= n; j++) {
      for (int k = 0; k < size; k++) {
        for (int l = 0; l < (1 << BIT_L); l++) {
          if (i > 0) {  // i-i j  //D
            nxt_st = ac_next('D', k, flag);
            dp[i][j][nxt_st][l | flag] += dp[i - 1][j][k][l];
            dp[i][j][nxt_st][l | flag] = mod(dp[i][j][nxt_st][l | flag]);
          }
          if (j > 0) {  // i j-1 R
            nxt_st = ac_next('R', k, flag);
            dp[i][j][nxt_st][l | flag] += dp[i][j - 1][k][l];
            dp[i][j][nxt_st][l | flag] = mod(dp[i][j][nxt_st][l | flag]);
          }
        }
      }
    }
  }
}
int main() {
  int T;
  string str;
  cin >> T;
  while (T--) {
    init();
    cin >> n >> m;
    for (int i = 0; i < BIT_L; i++) {
      cin >> str;
      insert(str, 1 << i);
    }
    makenxt();
    DP();
    int ans = 0;
    for (int i = 0; i < size; i++) {
      ans += dp[m][n][i][(1 << BIT_L) - 1];
      ans = mod(ans);
    }
    cout << ans << endl;
  }
  return 0;
}
